#ifndef JOLFS_ENTRY_H
#define JOLFS_ENTRY_H

#include <string>
#include <vector>
#include <boost/cstdint.hpp>

#include "tools.h"

#define OMODE(R,W,X) ((R) << 0 | (W) << 1 | (X) << 2)
#define GMODE(R,W,X) ((R) << 3 | (W) << 4 | (X) << 5)
#define UMODE(R,W,X) ((R) << 6 | (W) << 7 | (X) << 8)

namespace jolfs
{ 
  class Entry;
  
  typedef std::vector<Entry*> EntryList;
  
  class Entry
  {
  public:
    enum Type
    {
      FILE = 0,
      DIRECTORY,
      SYMBOLIC_LINK,
      SOCKET,
      NAMED_PIPE,
      CHARACTER_DEVICE,
      BLOCK_DEVICE,
      UNKNOWN
    };
    
    typedef std::string     name_t;
    typedef boost::uint64_t size_t;
    typedef time_t          timestamp_t;
    typedef boost::uint16_t mode_t;
    typedef unsigned char   type_t;
    typedef unsigned char   status_t;
    typedef boost::uint64_t id_t;
    
  public:
    const id_t&        getId()               const;
    const Entry*       getParent()           const;
    const name_t&      getName()             const;
    const size_t&      getSize()             const;
    const mode_t&      getMode()             const;
    const type_t&      getType()             const;
    const status_t&    getStatus()           const;
    const timestamp_t& getAccessTime()       const;
    const timestamp_t& getModificationTime() const;
    const timestamp_t& getCreationTime()     const;
    const EntryList&   getChildren()         const;
    EntryList&         getChildren();
    Entry*             getChild( const std::string& );
    const Entry*       getChild( const std::string& ) const;
    
    void setId              ( const id_t&        );
    void setParent          ( Entry* const       );
    void setName            ( const name_t&      );
    void setSize            ( const size_t&      );
    void setMode            ( const mode_t&      );
    void setType            ( const type_t&      );
    void setStatus          ( const status_t&    );
    void setAccessTime      ( const timestamp_t& );
    void setModificationTime( const timestamp_t& );
    void setCreationTime    ( const timestamp_t& );
    void addChild           ( Entry* const       );
    void delChild           ( Entry* const       );
    
  public:
    Entry();
    Entry( const Entry& );
    virtual ~Entry();
    
  protected:
    id_t        id_;
    Entry*      parent_;
    name_t      name_;
    size_t      size_;
    mode_t      mode_;
    type_t      type_;
    status_t    status_;
    timestamp_t atime_;
    timestamp_t mtime_;
    timestamp_t ctime_;
    EntryList   children_;
  };
} // namespace jolfs

#endif // JOLFS_ENTRY_H
